package com.canbot.u05.versionupdate

import android.os.Environment
import android.util.Log
import java.io.*
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
import org.apache.tools.zip.ZipFile

/**
 * @author wenshao<szujobs></szujobs>@hotmail.com>
 */
object ZipUtils {

    /**
     * 压缩文件
     *
     * @param folderPath
     * @param filePath
     * @param zipOut
     * @throws Exception
     */
    @Throws(Exception::class)
    @JvmStatic
    fun zipFiles(folderPath: String, filePath: String, zipOut: ZipOutputStream?) {
        if (zipOut == null) {
            return
        }
        val file = File(folderPath + filePath)

        // 判断是不是文件
        if (file.isFile) {
            val zipEntry = ZipEntry(filePath)
            val inputStream = FileInputStream(file)
            zipOut.putNextEntry(zipEntry)

            var len: Int
            val buffer = ByteArray(100000)
            do {
                len = inputStream.read(buffer)
                if (len != -1) {
                    zipOut.write(buffer, 0, len)
                }
            } while (true)

            inputStream.close()
            zipOut.closeEntry()
        } else {
            // 文件夹的方式,获取文件夹下的子文件
            val fileList = file.list()
            // 如果没有子文件, 则添加进去即可
            if (fileList!!.isEmpty()) {
                val zipEntry = ZipEntry(filePath + File.separator)
                zipOut.putNextEntry(zipEntry)
                zipOut.closeEntry()
            }
            // 如果有子文件, 遍历子文件
            for (i in fileList.indices) {
                zipFiles(folderPath, filePath + File.separator + fileList[i], zipOut)
            }
        }
    }

    // 解压资源文件
    @JvmStatic
    fun unZip(zipfile: String, targetdir: String, tag: String): Boolean {
        // 开始解压资源文件
        val zipFile = Environment.getExternalStorageDirectory().toString() + zipfile
        val targetDir = Environment.getExternalStorageDirectory().toString() + targetdir
        Log.e(tag, "source file:$zipFile")
        Log.e(tag, "targetDir:$targetDir")
        val size = 4096 // 这里缓冲区我们使用4KB，
        val strEntry: String // 保存每个zip的条目名称

        try {
            val dest: BufferedOutputStream? // 缓冲输出流
            val fis = FileInputStream(zipFile)
            val zis = ZipInputStream(BufferedInputStream(fis))
            var entry: ZipEntry // 每个zip条目的实例
            Log.e(tag, "zis is null?=" + zis.nextEntry)

            do {
                entry = zis.nextEntry
                if (entry != null) {
                    try {
                        Log.e(tag, "Unzip=$entry")
                        var count: Int
                        val data = ByteArray(size)
                        strEntry = entry.name
                        Log.e("Entry", entry.toString())
                        Log.e("strEntry", strEntry)
                        val entryFile = File(targetDir + strEntry)
                        val entryDir = File(entryFile.parent)
                        if (!entryDir.exists()) {
                            entryDir.mkdirs()
                        }
                        if (entryFile.exists()) {
                            entryFile.delete()
                        }
                        entryFile.createNewFile()

                        val fos = FileOutputStream(entryFile)
                        dest = BufferedOutputStream(fos, size)
                        do {
                            count = zis.read(data, 0, size)
                            if (count != -1) {
                                dest.write(data, 0, count)
                            }
                        } while (true)
                        dest.flush()
                        dest.close()
                    } catch (ex: Exception) {
                        ex.printStackTrace()
                        return false
                    }
                }
            } while (true)
            zis.close()
        } catch (cwj: Exception) {
            cwj.printStackTrace()
            return false
        }
        Log.i(tag, "Unzip done")
        return true
    }


    /**
     * 解压到指定目录
     *
     * @param zipPath
     * @param descDir
     */
    @Throws(IOException::class)
    @JvmStatic
    fun unZipFiles(zipPath: String, descDir: String): Boolean {
        return unZipFiles(File(zipPath), descDir)
    }

    /**
     * 解压文件到指定目录
     *
     * @param zipFile 压缩文件的名字
     * @param descDir 解压缩后存放的目录
     */
    @Throws(IOException::class)
    @JvmStatic
    fun unZipFiles(zipFile: File, descDir: String): Boolean {
        val pathFile = File(descDir)
        if (!pathFile.exists()) {
            pathFile.mkdirs()
        }

        val zip = ZipFile(zipFile, "GBK")
        val entries = zip.entries
        while (entries.hasMoreElements()) {
            val entry = entries.nextElement() as org.apache.tools.zip.ZipEntry
            val zipEntryName = entry.name
            println(zipEntryName)
            val `in` = zip.getInputStream(entry)
            val outPath = (descDir + zipEntryName).replace("\\", "/")
            // 输出文件路径信息
            println(outPath)
            // 判断路径是否存在,不存在则创建文件路径
            val file = File(outPath.substring(0, outPath.lastIndexOf('/')))
            if (!file.exists()) {
                file.mkdirs()
            }
            val outfile = File(outPath)
            // outfile.createNewFile();
            // 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
            if (outfile.isDirectory) {
                if (!outfile.exists()) {
                    outfile.mkdir()
                }
                continue
            } else {
                outfile.createNewFile()
            }
            val out = FileOutputStream(outfile)
            val buf1 = ByteArray(1024)
            var len: Int = 0
            while (`in`.read(buf1).also { len = it } > 0) {
                out.write(buf1, 0, len)
            }
            `in`.close()
            out.close()
        }
        return true
    }

}
